<template>
  <div class="chart-container">
    <div
      ref="myRef"
      :style="{ width: detail.position.w + 'px', height: detail.position.h + 'px' }"
    />
  </div>
</template>

<script lang="ts">
import {
  defineComponent,
  ref,
  toRefs,
  watch,
  onMounted,
  nextTick,
  onUnmounted,
  PropType
} from 'vue';
import * as echarts from 'echarts';
import { EChartsOption, EChartsType } from 'echarts'
import { CVariableDataItem, CGraphEntity, CDynamicDataItem, CDataNode } from 'stores/editorModels';
import { CChartPropertyItem } from 'components/views/chart/chartViewModel';
import api from 'axios';
import { useMessageNotify } from 'src/hook/common/useMessageNotify';


export default defineComponent({
  name: 'ViewChartMap',
  components: {
  },

  props: {
    detail: {
      type: Object,
      default: () => {
        return {} as CGraphEntity
      }
    },

    dynamicData: {
      type: Array as PropType<CVariableDataItem[]>,
      default: () => {
        return [] as CVariableDataItem[]
      }
    }
  },
  setup (props, context) {
    // 响应数据解构
    const {
      detail,
      dynamicData
    } = toRefs(props);

    //错误通知
    const {
      showMessage
    } = useMessageNotify();

    //chart数据样式
    let myRef = ref<HTMLElement | null>(null); //dom
    let param = ref<CChartPropertyItem>({
      title: '',
      areaColor: '',
      borderColor: '',
      labelColor: '',
      emphasisColor: '',
      visualMin: 0,
      visualMax: 0,
      xDataNum: 0
    });

    //初始化数据
    let xyData = ref<CDynamicDataItem[]>([
      {
        vid: 1,
        name: 'shandong',
        value: 80
      },
      {
        vid: 2,
        name: '广东',
        value: 100
      },
      {
        vid: 3,
        name: '江苏',
        value: 90
      },
      {
        vid: 4,
        name: '新疆',
        value: 20
      }
    ]);

    //对象实例
    let myChartInstance = {} as EChartsType; // 不是响应对象，否则会出错

    //地图显示文字
    let mapName = {
      北京市: '北京',
      天津市: '天津',
      上海市: '上海',
      重庆市: '重庆',
      黑龙江省: '黑龙江',
      吉林省: '吉林',
      辽宁省: '辽宁',
      山东省: '山东',
      新疆维吾尔自治区: '新疆',
      西藏自治区: '西藏',
      宁夏回族自治区: '宁夏',
      甘肃省: '甘肃',
      青海省: '青海',
      青藏自治区: '青藏',
      内蒙古自治区: '内蒙',
      陕西省: '陕西',
      山西省: '山西',
      河北省: '河北',
      河南省: '河南',
      四川省: '四川',
      云南省: '云南',
      江苏省: '江苏',
      安徽省: '安徽',
      浙江省: '浙江',
      江西省: '江西',
      福建省: '福建',
      广东省: '广东',
      湖北省: '湖北',
      湖南省: '湖南',
      贵州省: '贵州',
      广西壮族自治区: '广西',
      海南省: '海南',
      香港特别行政区: '香港',
      澳门特别行政区: '澳门',
      台湾省: '台湾'
    };

    //chart数据样式
    let myOption: EChartsOption = {
      title: {
        show: true,
        text: '中国地图',
        textStyle: {
          fontWeight: 'bolder',
          fontSize: 18
        }
      },
      tooltip: {
        show: true,
        trigger: 'item'
      },
      grid: {     //地图位置
        show: false,
        backgroundColor: 'transparent' //背景色
      },
      visualMap: {},   // 图例
      geo: [],
      series: []
    };

    //初始化地图
    const initMap = (): void => {
      // 获取地图数据,将下载后的json文件放置/public目录下
      api.get('./tuple/chinaMap.json').then((res) => {
        // 使用数据注册地图
        echarts.registerMap('china', res.data);

        //延时初始化地图
        nextTick(() => {
          myChartInstance = echarts.init(myRef.value as HTMLElement);
          init();
        });
      });
    };


    //修改参数
    const addToChart = (): void => {
      if (myOption.series) {
        (myOption.series as any).length = 0;
        (myOption.geo as any).length = 0;
        (myOption.title as any).text = param.value.title;

        //visualMap
        let map_item = {
          min: param.value.visualMin,
          max: param.value.visualMax,
          text: ['High', 'Low'],
          realtime: false,
          calculable: true,
          splitNumber: 3,
          inRange: {    //颜色数组
            color: [
              '#313695',
              '#74add1',
              '#e0f3f8',
              '#fee090',
              '#f46d43',
              '#a50026'
            ]
          }
        };
        myOption.visualMap = map_item;

        //Geo
        let geo_item = {
          // 地理坐标系组件
          map: 'china',  // echarts.registerMap名称
          roam: false, // 可以缩放和平移
          zoom: 1,
          aspectScale: 0.8, // 比例
          layoutCenter: ['50%', '60%'], // position位置
          layoutSize: 500, // 地图大小，保证了不超过 370x370 的区域

          //自定义命名映射，不设置的话，label默认是使用 geoJson中的name名
          nameMap: mapName,
          label: {  // 图形上的文本标签
            show: true,
            position: 'inside',
            color: param.value.labelColor,
            fontSize: '8',
            formatter: '{b}: {c}'
          },

          itemStyle: { // 所有地图的区域颜色
            // areaColor: detail.value.chart.itemStyle.areaColor,
            areaColor: param.value.areaColor,
            color: '#fff',
            borderColor: param.value.borderColor
          },
          emphasis: {  // 选中高亮区域颜色
            itemStyle: {
              areaColor: param.value.emphasisColor
            }
          },
          regions: [  // 隐藏不显示区域
            {
              name: '',
              itemStyle: {  // 隐藏地图
                opacity: 0  // 为 0 时不绘制该图形
              },
              label: {
                show: false // 隐藏文字
              }
            }
          ]
        };
        (myOption.geo as any).push(geo_item);

        //series
        let series_item = {
          name: param.value.title,
          type: 'map',
          map: 'china',
          geoIndex: 0,

          //这是要显示的数据
          data: xyData.value
        };

        (myOption.series as any).push(series_item);
      }
    }

    // 加载数据
    const setOption = () => {
      if (myChartInstance) {
        addToChart();
        myChartInstance.setOption(myOption);
      }
    }

    // 尺寸变化
    const onResize = () => {
      if (myChartInstance) {
        myChartInstance.resize();
      }
    };

    //属性更新
    const configProperty = () => {
      //个性化属性,计算长度，进行校验，一旦格式出错，涉及到数据错位，报错
      if ((detail.value?.propsItem) &&
        (detail.value?.propsItem.length > 0)) {
        //取出属性值
        let i = 0;
        let num1, num2, num3;
        param.value.title = (detail.value.propsItem[i++].value);
        param.value.areaColor = (detail.value.propsItem[i++].value);
        param.value.borderColor = (detail.value.propsItem[i++].value);
        param.value.labelColor = (detail.value.propsItem[i++].value);
        param.value.emphasisColor = (detail.value.propsItem[i++].value);
        num1 = parseInt((detail.value.propsItem[i++].value));
        num2 = parseInt((detail.value.propsItem[i++].value));
        num3 = parseInt((detail.value.propsItem[i++].value));
        if (!isNaN(num1) && !isNaN(num2) && !isNaN(num3)) {
          param.value.visualMin = num1;
          param.value.visualMax = num2;
          param.value.xDataNum = num3;
        } else {
          showMessage('ChartMap属性类型不正确！');
        }
      } else {
        showMessage('ChartMap属性数量不正确！');
      }

      //生成数据节点
      if ((detail.value.dataItem) &&
        (detail.value?.dataItem.length > 0)) {
        xyData.value.length = 0;
        detail.value.dataItem.forEach((item: CDataNode) => {
          xyData.value.push({
            vid: item.variableValue,
            name: item.nodeValue,
            value: 0
          });
        });
      }
    }

    //更新数据
    const refreshDynamicData = () => {
      //动态数据
      if ((dynamicData.value) && (dynamicData.value.length > 0)) {
        dynamicData.value.forEach((el, index) => {
          if (xyData.value[index].vid === el.varId) {
            xyData.value[index].value = el.vData;
          }
        });
      }
    }

    //初始化
    const init = () => {
      configProperty();
      refreshDynamicData();

      setOption();
      onResize();
    }

    // watch dom尺寸变化,调整子控件大小
    watch(() => detail, () => {
      init();
    }, { deep: true });

    //监视变量变化
    watch(() => dynamicData, () => {
      refreshDynamicData();
    }, { deep: true })

    //挂载组件
    onMounted(() => {
      //读取地图数据
      initMap();

      //跟随窗口变化
      window.addEventListener('resize', onResize);
    });

    // 卸载组件
    onUnmounted(() => {
      window.removeEventListener('resize', onResize);
    });

    return {
      myRef,
      detail
    };
  }
});
</script>

<style lang="scss" scoped>
.topo-container {
  position: absolute;
  left: 0px;
  top: 0px;
  width: 100%;
  height: 100%;
  text-align: center;
}
.topo-map {
  //background-color: #7de395;
}
</style>
